
import utils from './utils.js';

function writeStorage(key, value, expires) {

  const _expires = !utils.isNumber(expires) ? 60 * 60 * 24 : expires;

  const obj = {
    value: value,
    expires: _expires * 1000,
    startTime: new Date().getTime()
  }

  // 如果设置了时间，把obj转换数据类型转换为字符串对象存起来
  return localStorage.setItem(key, JSON.stringify(obj));
}

const m = {

  /**
   * 日期格式化
   * @param {Date} sometime 
   * @param {String} format 
   * @returns [string]
   * @example formatDate(new Date(e.value), 'yyyy.MM.dd')
   */
  formatDate: (sometime, format) => {

    let date = sometime;

    if (typeof sometime === 'string') {
      if (date.indexOf('-') > -1) {
        date = new Date(date.split('-')[0], date.split('-')[1] * 1 - 1, date.split('-')[2])
      } else if (date.indexOf('/') > -1) {
        date = new Date(date.split('/')[0], date.split('/')[1] * 1 - 1, date.split('/')[2])
      } else {
        date = new Date(date.substring(0, 4), date.substring(4, 6) * 1 - 1, date.substring(6, 8))
      }
    }

    if (!utils.isValidDate(date)) return date;

    const o = {
      "M+": date.getMonth() + 1, //月份
      "d+": date.getDate(), //日
      "h+": date.getHours(), //小时
      "m+": date.getMinutes(), //分
      "s+": date.getSeconds(), //秒
      "q+": Math.floor((date.getMonth() + 3) / 3), //季度
      "S": date.getMilliseconds() //毫秒
    };

    if (/(y+)/.test(format)) { 
      format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length))
    }

    for (var k in o){
      if (new RegExp("(" + k + ")").test(format)) {
        format = format.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
      }
    }
      
    return format;
  },

  /**
   * 生成字符串ID
   * @param {int} nsize - 唯一串长度
   * @returns 
   */
  nanoid(nsize) {

    const size = nsize || 21;

    const urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';

    let id = '';

    // A compact alternative for `for (let i = 0; i < step; i++)`.
    let i = size;
    while (i--) {
      // `| 0` is more compact and faster than `Math.floor()`.
      id += urlAlphabet[(Math.random() * 64) | 0];
    }

    return id;
  },


  /**
   * 将base64转成file(blob)类型，用于multipart/form-data方式的传输
   * @param {*} dataurl base64串
   * @returns 
   */
  dataUrlToBlob(dataurl) {

    if (!dataurl) return null;

    const arr = dataurl.split(',');
    const mime = arr[0].match(/:(.*?);/)[1];
    const bstr = atob(arr[1]);

    let n = bstr.length;
    const u8arr = new Uint8Array(n);

    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }

    return new Blob([u8arr], {
      type: mime
    });

  },

  /**
   * 获取缓存数据
   * @param {string} key - 需要获取的key 
   * @returns 
   */
  getStorage(key) {

    // 获取key对应的值
    const temp = JSON.parse(localStorage.getItem(key));

    // 有效期处理
    if (utils.isNumber(temp?.expires)) {

      const datetime = new Date().getTime();

      if (temp.expires <= 0 || (datetime - temp.startTime > temp.expires)) {
        // 丢弃过期数据
        localStorage.getItem(key);
        return null;
      } else {
        // 返回有效数据
        return temp.value
      }

    }

    return temp?.value ? temp.value : temp;

  },

  /**
   * 保存安全的缓存数据
   * @param {string} key 
   * @param {*} value 
   * @param {int} expires 过期时间-秒
   */
  setStorage(key, value, expires) {

    return writeStorage(key, value, expires);

  },

  /**
   * 更新缓存数据
   * @param {string} key 
   * @param {*} value 
   * @param {int} expires 过期时间-秒
   */
  updateStorage(key, value, expires) {

    // 先判断key是否存在，不存在的数据不可更新
    if (utils.isUndefined(localStorage.getItem(key)) || utils.isNull(localStorage.getItem(key))) {
      throw new Error(`the data of key(${key}) is not exist, can't update storage`);
    }

    return writeStorage(key, value, expires);

  },

  /**
   * 删除缓存数据
   * @param {*} key 
   * @returns 
   */
  removeStorage(key){

    if(key === true) {
      return localStorage.clear();
    }

    key && localStorage.removeItem(key);
  },

  /**
   * 解析queryString数据
   * @param {String} name 
   * @returns 
   */
  parseQueryString(name, search) {

    if (name && !utils.isString(name)) {
      throw new Error('arguments expect a string and accept not string.')
    }

    let searchStr = !search && location && location.search ? location.search : search;

    if (!searchStr) return null;

    const queryData = {};

    searchStr = searchStr.startsWith('?') ? searchStr.slice(1) : searchStr;

    for (const s of searchStr.split("&")) {

      const arr = s.split("=");

      if (!queryData[arr[0]]) {

        queryData[arr[0]] = arr[1];

      } else if (Array.isArray(queryData[arr[0]])) {

        queryData[arr[0]].push(arr[1]);

      } else {

        const values = [];
        values.push(queryData[arr[0]]);
        values.push(arr[1]);

        queryData[arr[0]] = values;
      }

    }

    return name && utils.isString(name) ? queryData[name] || '' : queryData;

  },

  /**
   * 校验ios环境
   * @returns if platform is ios return true, otherwise return false
   */
  isIos() {
    return !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
  },

  /**
   * 校验安卓环境
   * @returns if platform is android return true, otherwise return false
   */
  isAndroid() {
    return navigator.userAgent.indexOf('Android') > -1 || navigator.userAgent.indexOf('Adr') > -1
  },

  /**
   * 校验微信环境
   * @returns if is in wechat return true, otherwise return false
   */
  isWechat() {
    return navigator.userAgent.indexOf('MicroMessenger') > -1
  },

  /**
   * 校验微信小程序环境
   * @returns Promise
   */
  isWeChatMiniApp() {

    const ua = navigator.userAgent.toLowerCase();
    return new Promise((resolve, reject) => {
      if (ua.indexOf('micromessenger') === -1) {
        return reject(false)
      }

      wx.miniProgram.getEnv((res) => {
        if (res.miniprogram) resolve(true)
      })
    })
  }

}

export default m;